package com.ruoyi.portal.service;

import com.alibaba.fastjson.JSON;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.ListObjectsRequest;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.OSSObjectSummary;
import com.aliyun.oss.model.ObjectListing;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.portal.constant.Constant;
import com.ruoyi.portal.vo.AliYunConfigVO;
import com.ruoyi.system.domain.SysConfig;
import com.ruoyi.system.mapper.SysConfigMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.*;
import java.util.List;

/**
 * @author: cjie
 * @description: 阿里云文件上传
 * @date: 2021/5/8
 */
@Slf4j
@Service
public class FileUploadService {

    private static AliYunConfigVO aliYunConfigVO;
    @Resource
    private SysConfigMapper sysConfigMapper;

    public OSSClient getOssClient() {
        SysConfig source = new SysConfig();
        source.setConfigKey(Constant.CLOUD_STORAGE_CONFIG_KEY);
        SysConfig sysConfig = sysConfigMapper.selectConfig(source);
        aliYunConfigVO = JSON.parseObject(sysConfig.getConfigValue(),
                AliYunConfigVO.class);
        OSSClient ossClient = new OSSClient(aliYunConfigVO.getEndpoint(), aliYunConfigVO.getAccessKeyId(),
                aliYunConfigVO.getAccessKeySecret());
        return ossClient;
    }


    public AjaxResult upload(MultipartFile uploadFile) {
        OSSClient ossClient = getOssClient();
        String fileName = uploadFile.getOriginalFilename();
        String filePath = getFilePath(fileName);
        // 上传到阿里云
        try {
            ossClient.putObject(aliYunConfigVO.getBucketName(), filePath, new
                    ByteArrayInputStream(uploadFile.getBytes()));
        } catch (Exception e) {
            log.error("上传失败", e);
            //上传失败
            return AjaxResult.error("上传失败");
        }
        AjaxResult ajax = AjaxResult.success();
        ajax.put("url", aliYunConfigVO.getUrlPrefix()+filePath);
        return ajax;
    }

    /**
     * @author lastwhisper
     * @desc 生成路径以及文件名 例如：//files/2019/04/28/15564277465972939.jpg
     * @email gaojun56@163.com
     */
    private String getFilePath(String sourceFileName) {
        DateTime dateTime = new DateTime();
        return "files/" + dateTime.toString("yyyy")
                + "/" + dateTime.toString("MM") + "/"
                + dateTime.toString("dd") + "/" + System.currentTimeMillis() +
                RandomUtils.nextInt(100, 9999) + "." +
                StringUtils.substringAfterLast(sourceFileName, ".");
    }

    /**
     * @author lastwhisper
     * @desc 查看文件列表
     * 文档链接 https://help.aliyun.com/document_detail/84841.html?spm=a2c4g.11186623.2.13.3ad5b5ddqxWWRu#concept-84841-zh
     * @email gaojun56@163.com
     */
    public List<OSSObjectSummary> list() {
        OSSClient ossClient = getOssClient();
        // 设置最大个数。
        final int maxKeys = 200;
        // 列举文件。
        ObjectListing objectListing = ossClient.listObjects(new ListObjectsRequest(aliYunConfigVO.getBucketName()).withMaxKeys(maxKeys));
        List<OSSObjectSummary> sums = objectListing.getObjectSummaries();
        return sums;
    }

    /**
     * @author lastwhisper
     * @desc 删除文件  objectName指包含文件后缀在内的完整路径，例如abc/efg/123.jpg。
     * 文档链接 https://help.aliyun.com/document_detail/84842.html?spm=a2c4g.11186623.6.770.4f9474b4UYlCtr
     * @email gaojun56@163.com
     */
    public AjaxResult delete(String objectName) {
        OSSClient ossClient = getOssClient();
        // 根据BucketName,objectName删除文件
        ossClient.deleteObject(aliYunConfigVO.getBucketName(), objectName);
        return AjaxResult.success();
    }

    /**
     * @author lastwhisper
     * @desc 下载文件  objectName指包含文件后缀在内的完整路径，例如abc/efg/123.jpg。
     * 文档链接 https://help.aliyun.com/document_detail/84823.html?spm=a2c4g.11186623.2.7.37836e84ZIuZaC#concept-84823-zh
     * @email gaojun56@163.com
     */
    public void exportOssFile(OutputStream os, String objectName) throws IOException {
        // ossObject包含文件所在的存储空间名称、文件名称、文件元信息以及一个输入流。
        OSSClient ossClient = getOssClient();
        OSSObject ossObject = ossClient.getObject(aliYunConfigVO.getBucketName(), objectName);
        // 读取文件内容。
        BufferedInputStream in = new BufferedInputStream(ossObject.getObjectContent());
        BufferedOutputStream out = new BufferedOutputStream(os);
        byte[] buffer = new byte[1024];
        int lenght = 0;
        while ((lenght = in.read(buffer)) != -1) {
            out.write(buffer, 0, lenght);
        }
        if (out != null) {
            out.flush();
            out.close();
        }
        if (in != null) {
            in.close();
        }
    }
}
